package com.gd.iot.energy.service.superadmin.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.gd.iot.energy.code.ResponseCode;
import com.gd.iot.energy.consts.SystemConsts;
import com.gd.iot.energy.dao.superadmin.RolePOMapper;
import com.gd.iot.energy.dao.superadmin.RolePermissionPOMapper;
import com.gd.iot.energy.exception.MyException;
import com.gd.iot.energy.po.superadmin.AdminRolePO;
import com.gd.iot.energy.po.superadmin.RolePO;
import com.gd.iot.energy.pojo.superadmin.dto.AdminDTO;
import com.gd.iot.energy.pojo.superadmin.dto.RoleSaveDTO;
import com.gd.iot.energy.pojo.common.vo.ColumnVO;
import com.gd.iot.energy.pojo.common.vo.PageVO;
import com.gd.iot.energy.pojo.superadmin.vo.RolePageVO;
import com.gd.iot.energy.pojo.superadmin.vo.RoleVO;
import com.gd.iot.energy.service.superadmin.AdminService;
import com.gd.iot.energy.service.superadmin.PermissionService;
import com.gd.iot.energy.service.superadmin.RoleService;
import com.gd.iot.energy.util.*;
import org.apache.shiro.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 角色管理service
 *
 * @author kris
 * @date Created at 8:33 下午 2020/8/5
 */
@Service
public class RoleServiceImpl implements RoleService {

    @Resource
    private RolePOMapper rolePOMapper;

    @Resource
    private RolePermissionPOMapper rolePermissionPOMapper;

    @Autowired
    private PermissionService permissionService;

    @Autowired
    private AdminService adminService;

    /**
     * 表头文件
     */
    private static final String ROLE_LIST_COLUMN_FILE_NAME = "superadmin/role_list.column";

    @Override
    public List<RoleVO> getRoleVOs(String name) {
        QueryWrapper<RolePO> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("is_del", SystemConsts.BooleanEnum.FALSE.value);
        if (StrUtil.isNotBlank(name)) {
            queryWrapper.like("name", name);
        }
        EnergyTypeUtil.injectEnergyTypeWrapper(queryWrapper);
        List<RolePO> rolePOS = rolePOMapper.selectList(queryWrapper);
        List<RoleVO> roleVOList = new ArrayList<>(rolePOS.size());
        CustomBeanUtils.convertPojo(rolePOS, roleVOList, RoleVO.class);
        return roleVOList;
    }

    @Override
    public PageVO<RolePageVO> getPageRoleVOs(String name, Integer pageSize, Integer pageNum, String orderColumn, String orderType) {
        IPage<RolePO> page = new Page<>(pageNum, pageSize);
        QueryWrapper<RolePO> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("is_del", SystemConsts.BooleanEnum.FALSE.value);
        if (StrUtil.isNotBlank(name)) {
            queryWrapper.like("name", name.trim());
        }
        if (StrUtil.isNotBlank(orderColumn) && StrUtil.isNotBlank(orderType)) {
            orderColumn = CustomStrUtil.humpToLine(orderColumn);
            queryWrapper.orderBy(true, orderType.equals(SystemConsts.OrderType.ASC.value), orderColumn);
        }
        EnergyTypeUtil.injectEnergyTypeWrapper(queryWrapper);
        IPage<RolePO> rolePOIPage = rolePOMapper.selectPage(page, queryWrapper);
        PageVO<RolePageVO> pageVO = new PageVO<>();
        pageVO.setPageSize(pageSize);
        pageVO.setPageNum(pageNum);
        List<RolePageVO> roleVOList = convertToRolePageVOList(rolePOIPage.getRecords());
        pageVO.setData(roleVOList);
        pageVO.setTotal(rolePOIPage.getTotal());
        pageVO.setPages(rolePOIPage.getPages());

        //表头
        List<ColumnVO> columns = CustomColumnUtil.getColumn(ROLE_LIST_COLUMN_FILE_NAME);
        pageVO.setColumns(columns);
        return pageVO;
    }

    /**
     * 对象转换
     *
     * @param records
     * @return
     */
    private List<RolePageVO> convertToRolePageVOList(List<RolePO> records) {
        List<RolePageVO> res = new ArrayList<>(records.size());
        RolePageVO rolePageVO;
        int i = 1;
        for (RolePO record : records) {
            rolePageVO = new RolePageVO();
            rolePageVO.setSerialNum(i);
            rolePageVO.setId(record.getId());
            rolePageVO.setName(record.getName());
            rolePageVO.setDescription(record.getDescription());
            rolePageVO.setCreateDate(CustomDateUtil.formatDate(record.getCreateDate()));
            rolePageVO.setIsSystem(SystemConsts.BooleanEnum.getNameByValue(record.getIsSystem()));
            res.add(rolePageVO);
            i++;
        }
        return res;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Integer add(RoleSaveDTO roleSaveDTO) {
        if (StrUtil.isBlank(roleSaveDTO.getName())) {
            throw new MyException(ResponseCode.PARAMETER_REQUIRED);
        }
        RolePO rolePO = new RolePO();
        rolePO.setIsSystem(SystemConsts.BooleanEnum.FALSE.value);
        rolePO.setIsDel(SystemConsts.BooleanEnum.FALSE.value);
        rolePO.setDescription(roleSaveDTO.getDescription());
        rolePO.setName(roleSaveDTO.getName());
        rolePO.setCreateDate(new Date());
        rolePO.setAreaIds(CollUtil.isEmpty(roleSaveDTO.getAreaIds()) ? "" : StrUtil.join(",", roleSaveDTO.getAreaIds()));
        rolePO.setEquipmentIds(CollUtil.isEmpty(roleSaveDTO.getEquipmentmodelIds()) ? "" : StrUtil.join(",", roleSaveDTO.getEquipmentmodelIds()));
        rolePO.setEnergyType(SystemConsts.EnergyTypeEnum.WATER.value);

        AdminDTO adminDTO = CurrentUserUtil.getUserInfo();
        rolePO.setOperatorId(adminDTO.getId());

        int num = rolePOMapper.insert(rolePO);
        if (num > 0) {
            permissionService.savePermissions(roleSaveDTO.getPermissionIds(), rolePO.getId());
        }
        return rolePO.getId();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean update(RoleSaveDTO roleSaveDTO) {
        if (StrUtil.isBlank(roleSaveDTO.getName())||roleSaveDTO.getId() == null) {
            throw new MyException(ResponseCode.PARAMETER_REQUIRED);
        }
        RolePO rolePO = new RolePO();
        rolePO.setId(roleSaveDTO.getId());
        rolePO.setDescription(roleSaveDTO.getDescription());
        rolePO.setName(roleSaveDTO.getName());
        rolePO.setModifyDate(new Date());
        rolePO.setAreaIds(CollUtil.isEmpty(roleSaveDTO.getAreaIds()) ? "" : StrUtil.join(",", roleSaveDTO.getAreaIds()));
        rolePO.setEquipmentIds(CollUtil.isEmpty(roleSaveDTO.getEquipmentmodelIds()) ? "" : StrUtil.join(",", roleSaveDTO.getEquipmentmodelIds()));

        AdminDTO adminDTO = (AdminDTO) SecurityUtils.getSubject().getPrincipal();
        rolePO.setOperatorId(adminDTO.getId());

        int num = rolePOMapper.updateById(rolePO);
        if (num > 0) {
            permissionService.savePermissions(roleSaveDTO.getPermissionIds(), rolePO.getId());
        }
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean delete(List<Integer> ids) {
        if(CollUtil.isEmpty(ids)){
            throw new MyException(ResponseCode.PARAMETER_REQUIRED);
        }
        List<AdminRolePO> adminRolePOS = adminService.getAdminByRoleIds(ids);
        if(!adminRolePOS.isEmpty()){
            throw new MyException(ResponseCode.ROLE_ADMIN_HAS_RELATION);
        }

        //角色表逻辑删除
        QueryWrapper<RolePO> queryWrapper = new QueryWrapper<>();
        queryWrapper.in("id", ids);
        EnergyTypeUtil.injectEnergyTypeWrapper(queryWrapper);
        RolePO rolePO = new RolePO();
        rolePO.setIsDel(SystemConsts.BooleanEnum.TRUE.value);
        int num = rolePOMapper.update(rolePO,queryWrapper);

        return num > 0;
    }

    @Override
    public RoleSaveDTO getRole(Integer id) {
        RolePO rolePO = rolePOMapper.selectById(id);
        if(rolePO==null||SystemConsts.BooleanEnum.TRUE.value.equals(rolePO.getIsDel())){
            throw new MyException(ResponseCode.RECORD_NOT_EXIST);
        }

        RoleSaveDTO roleSaveDTO = new RoleSaveDTO();
        long[] areas = StrUtil.splitToLong(rolePO.getAreaIds(), ',');
        long[] equipmentmodels = StrUtil.splitToLong(rolePO.getEquipmentIds(), ',');
        roleSaveDTO.setAreaIds(CustomCollUtil.convertToLongList(areas));
        roleSaveDTO.setEquipmentmodelIds(CustomCollUtil.convertToLongList(equipmentmodels));
        roleSaveDTO.setName(rolePO.getName());
        roleSaveDTO.setDescription(rolePO.getDescription());
        roleSaveDTO.setId(rolePO.getId());
        roleSaveDTO.setPermissionIds(permissionService.getPermissionsByRoleId(rolePO.getId()));
        return roleSaveDTO;
    }
}
